package com.run.serial;

//import android.hardware.SerialPort;
import android.os.SystemClock;
import android.util.Log;

import androidx.annotation.NonNull;

import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Objects;
import java.util.concurrent.ConcurrentLinkedQueue;

public class SerialTxData {
    private static final String TAG = "SerialTxData";
    private static SerialTxData txData = null;
    private SerialPort serialPort;
    private OutputStream mOutputStream;
    private ByteBuffer outputBuffer;

    private RxDataCallBack rxDataCallBack = null;

    private ConcurrentLinkedQueue<SerialPkgData> sendPackageQueue = new ConcurrentLinkedQueue<SerialPkgData>();
    private ConcurrentLinkedQueue<SerialPkgData> cachepackageQueue = new ConcurrentLinkedQueue<SerialPkgData>();

    private SerialTxData() {
        outputBuffer = ByteBuffer.allocate(1024);
    }

    protected static SerialTxData getInstance() {
        if (txData == null) {
            synchronized (SerialTxData.class) {
                if (txData == null) {
                    txData = new SerialTxData();
                }
            }
        }
        return txData;
    }

    protected void setSerialPort(@NonNull SerialPort port) {
        serialPort = port;
        mOutputStream = serialPort.getOutputStream();
    }

    protected void setRxDataCallBack(RxDataCallBack callBack) {
        rxDataCallBack = callBack;
    }

    private synchronized void sendPackage(byte[] bytes, int length) {
        try {
//            outputBuffer.clear();
//            outputBuffer.put(bytes);
//            serialPort.write(outputBuffer, length);
            mOutputStream.write(bytes, 0, length);
            mOutputStream.flush();
//            if (rxDataCallBack != null) {
//                rxDataCallBack.sendData(bytes, length);
//            }
            Log.d("sendPackage ", ">> " + ConvertData.byteArrayToHexString(bytes, length));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    synchronized void sendPackage(byte[] bytes) {
        sendPackage(bytes, bytes.length);
    }

    protected synchronized boolean isEmptyQueue() {
        return sendPackageQueue.isEmpty();
    }

    protected byte[] reMoveUpClearQueue() {
        Log.d(TAG, "reMoveUpClearQueue");
        if(!cachepackageQueue.isEmpty()) {
            return cachepackageQueue.poll().data;
        }
        return new byte[]{};
    }

    synchronized void sendQueuePackage() {
    }

    synchronized SerialPkgData getQueueData() {
        if (!isEmptyQueue()) {
            return sendPackageQueue.poll();
        }
        return null;
    }

    synchronized void setQueueCache(SerialPkgData data) {
        cachepackageQueue.offer(data);
    }

    protected synchronized void sendPackageEnQueue( byte[] data) {
        if (data != null && data.length > 0) {
            SerialPkgData mSerialPkgData = new SerialPkgData();
            mSerialPkgData.id = SystemClock.elapsedRealtime();
            mSerialPkgData.data = new byte[data.length];
            System.arraycopy(data, 0, mSerialPkgData.data, 0, data.length);
            sendPackageQueue.offer(mSerialPkgData);
        }
    }

}
